package model.courtier;

import java.math.BigDecimal;
import java.util.ArrayList;

import org.hibernate.Query;

import model.donnee.Film;
import model.donnee.FilmLocation;
import model.singleton.HibernateUtil;

public class DAOLocation {
	
	public DAOLocation() 	{}
	
	/****
	 * getClientLocation : Cette méthode est utilisé pour récupérer tous les films loués d'un client.
	 * 
	 * @param idClient Le numéro du client.
	 * @return Les films associés au location actuelle du client.
	 */
	public static Film[] getClientLocations(int idClient)
	{
		// La requête envoyée à Hibernate.
		String queryExist = "SELECT fl.idFilm FROM FilmLocation fl WHERE idClient = " + idClient + " AND fl.DateRetour IS NULL";
		String query = "SELECT f.* FROM Film f WHERE f.idFilm IN (" + queryExist + ")";
		
		// Récupère les données de la base de données à l'aide d'Hibernate.
		@SuppressWarnings("unchecked")
		ArrayList<Film> films = (ArrayList<Film>) HibernateUtil.requete(query, Film.class);		
				
		return films.toArray(new Film[0]);
	}
	
	/****
	 * insertLocation : Cette méthode est utilisée pour réaliser la location d'un film.
	 * 
	 * @param loc L'objet de location.
	 * @return True si la location a été accepté.
	 */
	public static boolean insertLocation(FilmLocation loc)
	{
		HibernateUtil.getSession().beginTransaction();
		boolean peuxLouer = true;
		
		// Récupère le nombre de location possible.
		@SuppressWarnings("unchecked")
		ArrayList<BigDecimal> droitAllocation = (ArrayList<BigDecimal>) HibernateUtil.requete(
				"SELECT (LocationMax - (SELECT COUNT(*) AS FILMS_LOUER FROM Film f "
			+"WHERE f.idFilm IN (SELECT fl.idFilm FROM FilmLocation fl WHERE idClient ="+loc.getClient().getIdclient()+" AND fl.DateRetour IS NULL))) AS NB_FILM_RESTANT FROM Forfait f,Client c "
			+"WHERE c.idClient ="+loc.getClient().getIdclient()+" "
			+"and f.idForfait = c.idForfait");
		
		// Récupère les id des films déjà loué.
		@SuppressWarnings("unchecked")
		ArrayList<BigDecimal> dejaLouer = (ArrayList<BigDecimal>) HibernateUtil.requete(
				"SELECT f.idFilm AS FILMS_LOUER FROM Film f "
				+ "WHERE f.idFilm IN (SELECT fl.idFilm FROM FilmLocation fl WHERE idClient ="+loc.getClient().getIdclient()+" "
						+ "AND fl.DateRetour IS NULL "
						+ "AND idFilm = "+loc.getFilm().getIdfilm()+")");
		
		ArrayList<BigDecimal> maxFilm = (ArrayList<BigDecimal>) HibernateUtil.requete(
								"SELECT nbFilm FROM Film f "
								+ "WHERE idFilm = "+loc.getFilm().getIdfilm()+" "
										+ "AND f.nbFilm = 0");
		
		// Valide si l'on peut réaliser la location.
		for(int i = 0; i < (dejaLouer.size()) && peuxLouer != false; i++){
			if(dejaLouer.get(i).intValue() == (loc.getFilm().getIdfilm())){
				peuxLouer = false;
			}
		}
		
		if(droitAllocation.get(0) == BigDecimal.ZERO){
			peuxLouer = false;
		}
		else if(maxFilm.get(0) == BigDecimal.ZERO){
			peuxLouer = false;
		}
		
		
		// Réalise la location.
		if(peuxLouer){
			Query query = HibernateUtil.getSession().createSQLQuery(
					"CALL LOUERFILM(:idClient, :idFilm, :DATEESTIME)")
					.setParameter("idClient", loc.getClient().getIdclient())
					.setParameter("idFilm", loc.getFilm().getIdfilm())
					.setParameter("DATEESTIME", loc.getDateRetourEstime());
			query.executeUpdate();
		}
		HibernateUtil.getSession().getTransaction().commit();
		
		return peuxLouer;
	}
	

	/****
	 * insertLocation : Cette méthode est utilisée par le test unitaire.
	 * 
	 * @param loc L'objet de location.
	 * @return True si la location a été deleté.
	 */
	public static boolean deleteLocation(FilmLocation loc)
	{
		HibernateUtil.getSession().beginTransaction();

		Query query = HibernateUtil.getSession().createSQLQuery(
			"DELETE FROM FilmLocation "
			+"WHERE idFilm  ="+loc.getFilm().getIdfilm()
			+"AND idClient ="+loc.getClient().getIdclient()
			);
		query.executeUpdate();
		
		HibernateUtil.getSession().getTransaction().commit();
		return true;
	}
}
